home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / SESSION.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-18  |  11.2 KB  |  541 lines

  1. /* NOS User Session control
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by PA0GRI
  5.  */
  6. #include "global.h"
  7. #include "commands.h"
  8. #include "mbuf.h"
  9. #include "proc.h"
  10. #include "ftpcli.h"
  11. #include "icmp.h"
  12. #ifndef UNIX
  13. #include "main.h"
  14. #endif
  15.  
  16. #if !defined(_lint)
  17. static char rcsid[] OPTIONAL = "$Id: session.c,v 1.23 1997/08/19 01:19:22 root Exp root $";
  18. #endif
  19.  
  20. struct session *Sessions;
  21. struct session *Command;
  22. struct session *Current;
  23. struct session *Lastcurr;
  24. #ifndef UNIX
  25. extern unsigned char SCREENlength;
  26. #endif
  27. #ifdef UNIX
  28. extern int Numrows;
  29. #endif
  30.  
  31. extern int INStatline, BLOCKStatline;
  32. #if defined(UNIX)
  33. extern void statLineToggle (int clearmarquee);
  34. #endif
  35. static void upload (int unused,void *sp1,void *p);
  36.  
  37. char Notval[] = "Not a valid control block\n";
  38. static char Badsess[] = "Invalid session\n";
  39. char TooManySessions[] = "Too many sessions\n";
  40.  
  41. const char *Sestypes[] =
  42. {
  43.     "",            /* The command session */
  44.     "Telnet",
  45.     "FTP",
  46.     "AX25",
  47.     "Finger",
  48.     "Ping",
  49.     "NET/ROM",
  50.     "Command",
  51.     "More",
  52.     "Hopcheck",
  53.     "Tip",
  54.     "PPP PAP",
  55.     "Dial",
  56.     "Query",
  57.     "Cache",
  58.     "Rlogin",
  59. #ifdef UNIX
  60.     "Trace",
  61. #else
  62.     "",            /* The trace session */
  63. #endif
  64.     "View",
  65.     "Script",
  66.     "Repeat",
  67.     "Resolve",
  68.     "DNSquery",
  69.     "Look",
  70.     "AXUI"
  71. };
  72.  
  73.  
  74.  
  75. /* Convert a character string containing a decimal session index number
  76.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  77.  * If the index is out of range or unused, return NULLSESSION.
  78.  */
  79. struct session *
  80. sessptr (char *cp)
  81. {
  82. register struct session *sp;
  83. unsigned int i;
  84.  
  85.     if (cp == NULLCHAR)
  86.         sp = Lastcurr;
  87.     else {
  88.         i = (unsigned) atoi (cp);
  89.         if (i >= Nsessions)
  90.             sp = NULLSESSION;
  91.         else
  92.             sp = &Sessions[i];
  93.     }
  94.     if (sp == NULLSESSION || sp->type == FREE)
  95.         sp = NULLSESSION;
  96.  
  97.     return sp;
  98. }
  99.  
  100.  
  101.  
  102. /* Select and display sessions */
  103. int
  104. dosession (int argc, char *argv[], void *p)
  105. {
  106. struct session *sp;
  107. struct sockaddr fsocket;
  108. int i, k = 0, s;
  109. int r, t;
  110. char const *cp;
  111. char *param[3];
  112.  
  113.     sp = (struct session *) p;
  114.  
  115.     if (argc > 1) {
  116.         if ((sp = sessptr (argv[1])) == NULLSESSION) {
  117.             tprintf ("Session %s not active\n", argv[1]);
  118.             return 1;
  119.         }
  120.         if (argc == 2)
  121.             (void) go (0, NULL, sp);
  122.  
  123.         param[0] = argv[2];
  124.         param[1] = argv[3];
  125.         param[2] = NULL;
  126.         if (argc > 2) {
  127.             switch (*argv[2]) {
  128.                 case 'f':    /* flowmode */
  129.                     (void) setbool (&sp->flowmode, "Set flowmode on/off", argc - 2, param);
  130.                     break;
  131.                 default:
  132.                     tputs ("usage:session # [flow [on/off]]\n");
  133.             }
  134.         }
  135.         return 0;
  136.     }
  137.     tputs (" #  S#  Type     Rcv-Q Snd-Q State        Remote socket\n");
  138.     for (sp = Sessions; sp < &Sessions[Nsessions]; sp++) {
  139.         if (sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
  140.             continue;
  141.  
  142.         /* Rcv-Q includes output pending at the screen driver */
  143.         r = socklen (sp->output, 1);
  144.         t = 0;
  145.         cp = NULLCHAR;
  146.         if ((s = sp->s) != -1) {
  147.             i = SOCKSIZE;
  148.             s = sp->s;
  149.             k = getpeername (s, (char *) &fsocket, &i);
  150.             r += socklen (s, 0);
  151.             t += socklen (s, 1);
  152.             cp = sockstate (s);
  153.         }
  154.         tprintf ("%c", (Lastcurr == sp) ? '*' : ' ');
  155.         tprintf ("%-3u", (unsigned) (sp - Sessions));
  156.         tprintf ("%-4d%-8s%6d%6d %-13s", s, Sestypes[sp->type], r, t,
  157.              (cp != NULLCHAR) ? cp : "Limbo!");
  158.         if (sp->name != NULLCHAR)
  159.             tprintf ("%s ", sp->name);
  160.         if (sp->s != -1 && k == 0)
  161.             tprintf ("(%s)", psocket (&fsocket));
  162.  
  163.         tputc ('\n');
  164.         if (sp->type == FTP && (s = sp->cb.ftp->data) != -1) {
  165.             /* Display data channel, if any */
  166.             i = SOCKSIZE;
  167.             k = getpeername (s, (char *) &fsocket, &i);
  168.             r = socklen (s, 0);
  169.             t = socklen (s, 1);
  170.             cp = sockstate (s);
  171.             tprintf ("    %-4d%-8s%6d%6d %-13s%s", s, Sestypes[sp->type],
  172.                  r, t, (cp != NULLCHAR) ? cp : "Limbo!",
  173.                  (sp->name != NULLCHAR) ? sp->name : "");
  174.             if (k == 0)
  175.                 tprintf (" (%s)", psocket (&fsocket));
  176.             if (tputc ('\n') == EOF)
  177.                 break;
  178.         }
  179.         if (sp->rfile != NULLCHAR)
  180.             tprintf ("    Record: %s\n", sp->rfile);
  181.         if (sp->ufile != NULLCHAR)
  182.             tprintf ("    Upload: %s\n", sp->ufile);
  183.     }
  184.     return 0;
  185. }
  186.  
  187.  
  188.  
  189. /* Resume current session, and wait for it */
  190. int
  191. go (int argc OPTIONAL, char *argv[] OPTIONAL, void *p)
  192. {
  193. struct session *sp;
  194.  
  195.     sp = (struct session *) p;
  196.     if (sp == NULLSESSION || sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
  197.         return 0;
  198.     Current = sp;
  199.     swapscreen (Command, sp);
  200.     ksignal (sp, 0);
  201.     return 0;
  202. }
  203.  
  204.  
  205.  
  206. int
  207. doclose (int argc, char *argv[], void *p)
  208. {
  209. struct session *sp;
  210.  
  211.     sp = (struct session *) p;
  212.     if (argc > 1)
  213.         sp = sessptr (argv[1]);
  214.  
  215.     if (sp == NULLSESSION) {
  216.         tputs (Badsess);
  217.         return -1;
  218.     }
  219.     (void) shutdown (sp->s, 1);
  220.     return 0;
  221. }
  222.  
  223.  
  224.  
  225. int
  226. doreset (int argc, char *argv[], void *p)
  227. {
  228. struct session *sp;
  229.  
  230.     sp = (struct session *) p;
  231.     if (argc > 1)
  232.         sp = sessptr (argv[1]);
  233.  
  234.     if (sp == NULLSESSION) {
  235.         tputs (Badsess);
  236.         return -1;
  237.     }
  238.     /* Unwedge anyone waiting for a domain resolution, etc */
  239.     alert (sp->proc, EABORT);
  240.     (void) shutdown (sp->s, 2);
  241.     if (sp->type == FTP)
  242.         (void) shutdown (sp->cb.ftp->data, 2);
  243.     return 0;
  244. }
  245.  
  246.  
  247.  
  248. int
  249. dokick (int argc, char *argv[], void *p)
  250. {
  251. struct session *sp;
  252.  
  253.     sp = (struct session *) p;
  254.     if (argc > 1)
  255.         sp = sessptr (argv[1]);
  256.  
  257.     if (sp == NULLSESSION) {
  258.         tputs (Badsess);
  259.         return -1;
  260.     }
  261.     (void) sockkick (sp->s);
  262.     if (sp->type == FTP)
  263.         (void) sockkick (sp->cb.ftp->data);
  264.     return 0;
  265. }
  266.  
  267.  
  268. #ifdef UNIX
  269. extern int STATLINE;
  270. #endif
  271.  
  272.  
  273.  
  274. struct session *
  275. newsession (const char *name, int type, int split)
  276. {
  277. register struct session *sp;
  278. int i;
  279.  
  280.     /* Reserve the highest session for Trace, so that
  281.      * the F-key session switching works correctly - WG7J
  282.      */
  283.     if (type == TRACESESSION) {    /* This can only get called once !! */
  284.         i = 0;
  285.         sp = Sessions;
  286.         while ((unsigned) i != Nsessions - 1) {
  287.             i++;
  288.             sp++;
  289.         }
  290.     } else {
  291.         for (i = 0, sp = Sessions; (unsigned) i < Nsessions; sp++, i++)
  292.             if (sp->type == FREE)
  293.                 break;
  294.     }
  295.     if ((unsigned) i == Nsessions)
  296.         return NULLSESSION;
  297.  
  298.     sp->type = type;
  299.     sp->s = -1;
  300.     if (name != NULLCHAR)
  301.         sp->name = strdup (name);
  302.     else
  303.         sp->name = NULLCHAR;
  304.     sp->proc = Curproc;
  305. #ifdef UNIX
  306.     /* update Curproc's session pointer as well! */
  307.     /* (in theory this could leave a dangling session...?) */
  308.     Curproc->session = sp;
  309. #endif
  310.     /* Create standard input and output sockets. Output is
  311.      * translated to local end-of-line by default
  312.      */
  313.     Curproc->input = sp->input = socket (AF_LOCAL, SOCK_STREAM, 0);
  314.     (void) seteol (Curproc->input, Eol);
  315.     (void) sockmode (Curproc->input, SOCK_BINARY);
  316.     Curproc->output = sp->output = socket (AF_LOCAL, SOCK_STREAM, 0);
  317.     (void) seteol (Curproc->output, Eol);
  318.     (void) sockmode (Curproc->output, SOCK_ASCII);
  319.  
  320.     /* on by default */
  321.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  322.     sp->flowmode = 0;    /* Off by default */
  323. #ifdef UNIX
  324.     sp->row = Numrows - 1 - (split * 2);
  325. #else
  326.     sp->row = SCREENlength - 1 - (split * 2);
  327. #endif
  328.     sp->morewait = 0;
  329.     sp->split = split;
  330.     newscreen (sp);
  331.     swapscreen (Current, sp);
  332.     Current = sp;
  333. #ifdef UNIX
  334.     sp->screen->statline = uchar (STATLINE);
  335.     if (STATLINE) {
  336.         statLineToggle (0);
  337.         statLineToggle (0);
  338.     }
  339. #endif
  340.     return sp;
  341. }
  342.  
  343.  
  344.  
  345. void
  346. freesession (struct session *sp)
  347. {
  348.     if (sp == NULLSESSION)
  349.         return;
  350.     kwait (NULL);        /* Wait for any pending output to go */
  351.     rflush ();
  352.  
  353.     if (sp->proc1 != NULLPROC)
  354.         killproc (sp->proc1);
  355.     sp->proc1 = NULLPROC;
  356.     if (sp->proc2 != NULLPROC)
  357.         killproc (sp->proc2);
  358.     sp->proc2 = NULLPROC;
  359.  
  360.     free_p (sp->ttystate.line);
  361.     sp->ttystate.line = NULLBUF;
  362.     if (sp->s != -1)
  363.         close_s (sp->s);
  364.     if (sp->record != NULLFILE) {
  365.         (void) fclose (sp->record);
  366.         sp->record = NULLFILE;
  367.     }
  368.     free (sp->rfile);
  369.     sp->rfile = NULLCHAR;
  370.     if (sp->upload != NULLFILE) {
  371.         (void) fclose (sp->upload);
  372.         sp->upload = NULLFILE;
  373.     }
  374.     free (sp->ufile);
  375.     sp->ufile = NULLCHAR;
  376.     free (sp->name);
  377.     sp->name = NULLCHAR;
  378.     sp->type = FREE;
  379.  
  380.     close_s (sp->input);
  381.     sp->input = -1;
  382.     sp->proc->input = -1;
  383.     close_s (sp->output);
  384.     sp->output = -1;
  385.     sp->proc->output = -1;
  386.  
  387.     sp->screen->statline = 0;
  388.  
  389.     while (INStatline)
  390.         kwait (NULL);
  391.     BLOCKStatline += 1;
  392.  
  393.     freescreen (sp);
  394.     if (Current == sp) {
  395.         Current = Command;
  396.         swapscreen (NULLSESSION, Command);
  397. #ifndef UNIX
  398.         alert (Display, 1);
  399. #endif
  400.     }
  401. #ifdef UNIX
  402.     /* reparent process to command session */
  403.     sp->proc->session = Command;
  404. #endif
  405.     BLOCKStatline -= 1;
  406.     if (Lastcurr == sp)
  407.         Lastcurr = NULLSESSION;
  408. }
  409.  
  410.  
  411.  
  412. #ifdef ALLCMD
  413. /* Control session recording */
  414. int
  415. dorecord (int argc, char *argv[], void *p)
  416. {
  417. struct session *sp;
  418. char const *mode;
  419. char fname[128];
  420.  
  421.     sp = (struct session *) p;
  422.     if (sp == NULLSESSION) {
  423.         tputs ("No current session\n");
  424.         return 1;
  425.     }
  426.     if (argc > 1) {
  427.         if (sp->rfile != NULLCHAR) {
  428.             (void) fclose (sp->record);
  429.             free (sp->rfile);
  430.             sp->record = NULLFILE;
  431.             sp->rfile = NULLCHAR;
  432.         }
  433.         /* Open new record file, unless file name is "off", which means
  434.          * disable recording
  435.          */
  436.         if (strcmp (argv[1], "off") != 0) {
  437.             if (sockmode (sp->output, -1) == SOCK_ASCII)
  438.                 mode = APPEND_TEXT;
  439.             else
  440.                 mode = APPEND_BINARY;
  441.  
  442.             strncpy (fname, make_fname (Command->curdirs->dir, argv[1]), 128);
  443.             if ((sp->record = fopen (fname, mode)) == NULLFILE)
  444.                 tprintf ("Can't open %s: %s\n", fname, SYS_ERRLIST(errno));
  445.             else
  446.                 sp->rfile = strdup (fname);
  447.         }
  448.     }
  449.     if (sp->rfile != NULLCHAR)
  450.         tprintf ("Recording into %s\n", sp->rfile);
  451.     else
  452.         tputs ("Recording off\n");
  453.     return 0;
  454. }
  455.  
  456.  
  457.  
  458. /* Control file transmission */
  459. int
  460. doupload (int argc, char *argv[], void *p)
  461. {
  462. register struct session *sp;
  463. char fname[128];
  464.  
  465.     sp = (struct session *) p;
  466.     if (sp == NULLSESSION) {
  467.         tputs ("No current session\n");
  468.         return 1;
  469.     }
  470.     if (argc < 2) {
  471.         if (sp->ufile != NULLCHAR)
  472.             tprintf ("Uploading %s\n", sp->ufile);
  473.         else
  474.             tputs ("Uploading off\n");
  475.         return 0;
  476.     }
  477.     if (strcmp (argv[1], "stop") == 0 && sp->upload != NULLFILE) {
  478.         /* Abort upload */
  479.         (void) fclose (sp->upload);
  480.         sp->upload = NULLFILE;
  481.         free (sp->ufile);
  482.         sp->ufile = NULLCHAR;
  483.         killproc (sp->proc2);
  484.         sp->proc2 = NULLPROC;
  485.         return 0;
  486.     }
  487.     /* Open upload file */
  488.     strncpy (fname, make_fname (Command->curdirs->dir, argv[1]), 128);
  489.     if ((sp->upload = fopen (fname, READ_TEXT)) == NULLFILE) {
  490.         tprintf ("Can't read %s: %s\n", fname, SYS_ERRLIST(errno));
  491.         return 1;
  492.     }
  493.     sp->ufile = strdup (fname);
  494.     /* All set, invoke the upload process */
  495.     sp->proc2 = newproc ("upload", 1024, upload, 0, sp, NULL, 0);
  496.     return 0;
  497. }
  498.  
  499.  
  500.  
  501. /* File uploading task */
  502. static void
  503. upload (int unused OPTIONAL, void *sp1, void *p OPTIONAL)
  504. {
  505. struct session *sp;
  506. int oldf;
  507. char *buf;
  508.  
  509.     sp = (struct session *) sp1;
  510.  
  511.     /* Disable newline buffering for the duration */
  512.     oldf = setflush (sp->s, -1);
  513.  
  514.     buf = mallocw (BUFSIZ);
  515.     while (fgets (buf, BUFSIZ, sp->upload) != NULLCHAR)
  516.         if (usputs (sp->s, buf) == EOF)
  517.             break;
  518.  
  519.     free (buf);
  520.     usflush (sp->s);
  521.     (void) setflush (sp->s, oldf);
  522.     (void) fclose (sp->upload);
  523.     sp->upload = NULLFILE;
  524.     free (sp->ufile);
  525.     sp->ufile = NULLCHAR;
  526.     sp->proc2 = NULLPROC;
  527. }
  528. #endif /*ALLCMD*/
  529.  
  530.  
  531.  
  532. /* Flush the current session's standard output. Called on every clock tick */
  533. void
  534. sesflush(void)
  535. {
  536.     if (Current != NULL)
  537.         usflush (Current->output);
  538. }
  539.  
  540.  
  541.